package com.kuizii.jarencrypt.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardOpenOption;
import java.security.SecureRandom;

public class DecryptUtil {


    static String algorithm = "AES/ECB/PKCS5Padding";

    public static void DecryptClass(File file, String key) throws Exception {
        if (!file.exists()) {
            return;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File child : files) {
                DecryptClass(child, key);
            }
        } else if (file.isFile() && file.getName().endsWith(".xclass")) {

            byte[] bytes = new byte[(int)file.length()];
            //将缓冲区的数据存放在byte数组中，bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方
            ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
            FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
            while (fileChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();
            }

            String encryptedContent = doAesEncrypt(bytes, key);
            FileChannel targetChannel = new FileOutputStream(file.getPath().replace(".xclass", ".class"),false).getChannel();

            targetChannel.write(ByteBuffer.wrap(encryptedContent.getBytes(StandardCharsets.UTF_8)));
        }
    }


    public static String doAesEncrypt(byte[] data, String key) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128, new SecureRandom(key.getBytes()));
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();

        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(enCodeFormat,"AES"));
        byte[] bytes = cipher.doFinal(data);
        return new String(bytes, Charset.forName("utf-8"));
    }
}
